package com.sailfish.springbootdemo.service.db4;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.sailfish.springbootdemo.controller.db4.Role;
import com.sailfish.springbootdemo.dao.db4.RoleDao;
import com.sailfish.springbootdemo.dao.db4.UserDao;
import com.sailfish.springbootdemo.dao.db4.UsergroupDao;
import com.sailfish.springbootdemo.dao.db5.EmpTAdmpAdgroupDao;
import com.sailfish.springbootdemo.dao.db5.EmpTDepartmentsDao;
import com.sailfish.springbootdemo.dao.db5.EmpTPublicStaffDao;
import com.sailfish.springbootdemo.pojo.Result;
import com.sailfish.springbootdemo.pojo.db4.LoginRecord;
import com.sailfish.springbootdemo.pojo.db4.User;
import com.sailfish.springbootdemo.pojo.db4.Usergroup;
import com.sailfish.springbootdemo.pojo.db5.EmpTAdmpAdgroup;
import com.sailfish.springbootdemo.pojo.db5.EmpTDepartments;
import com.sailfish.springbootdemo.pojo.db5.EmpTPublicStaff;
import com.sailfish.springbootdemo.utils.HttpUtil;
import com.sailfish.springbootdemo.utils.Md5Util;
import com.sailfish.springbootdemo.utils.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private RoleDao roleDao;

    @Autowired
    private EmpTPublicStaffDao empTPublicStaffDao;

    @Autowired
    private EmpTDepartmentsDao empTDepartmentsDao;

    @Autowired
    private EmpTAdmpAdgroupDao empTAdmpAdgroupDao;

    @Autowired
    private UsergroupDao usergroupDao;

    @Autowired
    private LoginRecordService loginRecordService;

    @Qualifier("MysqlTransactionManager1")
    @Autowired
    private DataSourceTransactionManager transactionManager1;

    @Value("${personal.config.jwt.expiration-time}")
    private Integer expirationTime;

    @Value("${personal.config.jwt.sign}")
    private String sign;

    @Value("${personal.config.user.initial-password}")
    private String initialPassword;

    @Value("${personal.config.ip-check}")
    private String ipCheck;

    @Value("${personal.config.get-ip-address-api}")
    private String getIpAddressApi;

    private Result<?> result;

    @Override
    public Result<?> getUserInfoById(Integer userId) {
        try {
            if (userId == null || "".equals(userId.toString())) {
                return ResultUtil.error(500, "缺少参数userId", "Miss Param userId", null);
            }
            return ResultUtil.success(userDao.getUserInfoById(userId));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }

    @Override
    public Result getUserByDept(Integer dept) {
        List<User> userInfoByDepts = null;
        if (dept == 0) {
            userInfoByDepts = userDao.getUserInfoByDept(null);
        } else {
            userInfoByDepts = userDao.getUserInfoByDept(dept);
        }
        return ResultUtil.success(userInfoByDepts);
    }

    @Override
    public Result<?> login(String userName, String password, String ipAddress) {
        try {
            if (userName == null || "".equals(userName)) {
                return ResultUtil.error(500, "缺少参数userName", "Miss Param userName", null);
            }
            if (password == null || "".equals(password)) {
                return ResultUtil.error(500, "缺少参数password", "Miss Param password", null);
            }
            if (ipAddress == null || "".equals(ipAddress)) {
                return ResultUtil.error(500, "未获取到ip", "Not Get IP", null);
            }

            LoginRecord loginRecord = new LoginRecord();

            Map<String, Object> map = new HashMap<>();
            Map<String, Object> userInfo = new HashMap<>();

            String encryptedPassword = Md5Util.encryptPwd(password);
            User user = userDao.login(userName, encryptedPassword);
            if (user != null) {

                EmpTPublicStaff empTPublicStaffByDomainAccount = empTPublicStaffDao.getEmpTPublicStaffByDomainAccount(user.getDomainAccount());
                if (empTPublicStaffByDomainAccount == null) {
                    return ResultUtil.error(500, "未找到对应用户,可能用户已离职或者Emp表未同步", "Not Found User", null);
                }

                if (user.getIsInner() == 2) {
                    // h3c外场人员
                    if ((user.getBelongPcb() == null || "".equals(user.getBelongPcb().toString())) && (user.getBelongPcba() == null || "".equals(user.getBelongPcba().toString()))) {
                        return ResultUtil.error(500, "当前用户是外场人员，请联系管理员设置所属板厂或CM厂", "User Set Error", null);
                    }
                }

                EmpTDepartments empTDepartmentsByDeptCode = empTDepartmentsDao.getEmpTDepartmentsByDeptCode(empTPublicStaffByDomainAccount.getDeptCode());
                if (empTDepartmentsByDeptCode == null) {
                    return ResultUtil.error(500, "未获取到当前用户的部门号", "Not Get DeptCode", null);
                }

                String groupStr = "";

                loginRecord.setUserId(user.getUserId());
                loginRecord.setIpAddress(ipAddress);

                if (ipCheck != null && ipCheck.contains("pro")) {
                    // h3c 正式环境 检查ip
                    String typeId = empTDepartmentsByDeptCode.getTypeId();
                    String res = HttpUtil.sendGetRequest(getIpAddressApi + "?address=" + ipAddress);
                    System.out.println("getIpAddressApi:return" + res);
                    JSONObject resObj = JSONObject.parseObject(res);
                    if ("200".equals(resObj.get("statusCode").toString())) {
                        groupStr = resObj.getJSONObject("data").getString("group");
                        // 含  黄云、黄区、红云、红区  为研发，其余非研发
                        if ("RD".equals(typeId)) {
                            // 研发段 只能在 研发段 登
                            if (!groupStr.contains("黄云") && !groupStr.contains("黄区") && !groupStr.contains("红云") && !groupStr.contains("红区")) {
                                loginRecord.setNetworkSeg(groupStr);
                                loginRecord.setFailReason("当前用户研发，登录ip非研发，禁止登陆");
                                loginRecord.setLoginResult("失败");
                                return ResultUtil.error(500, "当前用户研发，登录ip非研发，禁止登陆", "Forbidden Login", null);
                            }
                        } else {
                            // 非研发段 只能在 非研发段 登
                            if (groupStr.contains("黄云") || groupStr.contains("黄区") || groupStr.contains("红云") || groupStr.contains("红区")) {
                                loginRecord.setNetworkSeg(groupStr);
                                loginRecord.setFailReason("当前用户非研发，登录ip研发，禁止登陆");
                                loginRecord.setLoginResult("失败");
                                return ResultUtil.error(500, "当前用户非研发，登录ip研发，禁止登陆", "Forbidden Login", null);
                            }
                        }
                    } else {
                        loginRecord.setNetworkSeg(groupStr);
                        loginRecord.setFailReason(resObj.get("msg").toString());
                        loginRecord.setLoginResult("失败");
                        return ResultUtil.error(500, resObj.get("msg").toString(), resObj.get("msg").toString(), null);
                    }
                }

                userInfo.put("dashboard", user.getDashboard());
                userInfo.put("userId", user.getUserId());
                userInfo.put("nickNameCn", empTPublicStaffByDomainAccount.getPreferredName());
                userInfo.put("nickNameEn", empTPublicStaffByDomainAccount.getPreferredName());

                String roleNameStr = "";
                String roleStrSys = user.getRoleSys();
                String roleStrBase = user.getRoleBase();
                String roleStrTech = user.getRoleTech();
                String[] roleArrSys = (roleStrSys != null && !"".equals(roleStrSys)) ? roleStrSys.split(",") : null;
                String[] roleArrBase = (roleStrBase != null && !"".equals(roleStrBase)) ? roleStrBase.split(",") : null;
                String[] roleArrTech = (roleStrTech != null && !"".equals(roleStrTech)) ? roleStrTech.split(",") : null;
                if(roleArrSys != null){
                    for (String s : roleArrSys) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }
                if(roleArrBase != null){
                    for (String s : roleArrBase) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }
                if(roleArrTech != null){
                    for (String s : roleArrTech) {
                        Role r = roleDao.getRoleById(Integer.parseInt(s));
                        if (r != null) {
                            String roleNameCn = r.getRoleNameCn();
                            if (roleNameCn != null && !"".equals(roleNameCn)) {
                                roleNameStr = roleNameStr + roleNameCn + ",";
                            }
                        }
                    }
                }

                // 上面为基本的用户角色配置
                // 以下为用户组中的角色配置
                String member = user.getDisplayName() + " " + user.getNotesId();
                List<EmpTAdmpAdgroup> empTAdmpAdgroupList = empTAdmpAdgroupDao.getByMember(member);
                for (EmpTAdmpAdgroup empTAdmpAdgroup : empTAdmpAdgroupList) {
                    String group_name = empTAdmpAdgroup.getGroup_name();
                    if(group_name != null && !"".equals(group_name)){
                        Usergroup usergroup = usergroupDao.getByName(group_name);
                        if(usergroup != null){
                            List<Role> roleListByUserGroupId = roleDao.getRoleListByUserGroupId(usergroup.getId());
                            for (Role role : roleListByUserGroupId) {
                                String roleNameCn = role.getRoleNameCn();
                                if (roleNameCn != null && !"".equals(roleNameCn)) {
                                    roleNameStr = roleNameStr + roleNameCn + ",";
                                }
                            }
                        }
                    }
                }

                if (roleNameStr.length() > 0) {
                    roleNameStr = roleNameStr.substring(0, roleNameStr.length() - 1);
                }
                if ("".equals(roleNameStr)) {
                    return ResultUtil.error(500, "该用户未配置角色，请联系管理员配置", "Not Set Role", null);
                }

                userInfo.put("role", roleNameStr);

                map.put("userInfo", userInfo);

                List<Integer> roleList = new ArrayList<>();
                if(roleArrSys != null){
                    for (String s : roleArrSys) {
                        roleList.add(Integer.parseInt(s));
                    }
                }
                if(roleArrBase != null){
                    for (String s : roleArrBase) {
                        roleList.add(Integer.parseInt(s));
                    }
                }
                if(roleArrTech != null){
                    for (String s : roleArrTech) {
                        roleList.add(Integer.parseInt(s));
                    }
                }

                Calendar instance = Calendar.getInstance();
                instance.add(Calendar.MINUTE, expirationTime);
                String token = JWT.create()
                        .withHeader(map)//添加头部
                        .withClaim("userId", user.getUserId().toString())//添加payload
                        .withClaim("userName", user.getUserName())
                        .withClaim("password", user.getPassword())
                        .withClaim("role", user.getRole())
                        .withClaim("roleList", roleList)
                        .withClaim("domainAccount", user.getDomainAccount())
                        .withClaim("isInner", user.getIsInner() != null && !"".equals(user.getIsInner().toString()) ? user.getIsInner().toString() : "")
                        .withClaim("belongPcb", user.getBelongPcb() != null && !"".equals(user.getBelongPcb().toString()) ? user.getBelongPcb().toString() : "")
                        .withClaim("belongPcba", user.getBelongPcba() != null && !"".equals(user.getBelongPcba().toString()) ? user.getBelongPcba().toString() : "")
                        .withClaim("pcbas", user.getPcbas() != null && !"".equals(user.getPcbas()) ? user.getPcbas() : "")
                        .withClaim("pcbs", user.getPcbs() != null && !"".equals(user.getPcbs()) ? user.getPcbs() : "")
                        .withClaim("networkSeg", groupStr)
                        .withClaim("ipAddress", ipAddress)
                        .withExpiresAt(instance.getTime())//设置过期时间
                        .sign(Algorithm.HMAC256(sign));//设置签名 密钥
                map.put("token", token);

                loginRecord.setNetworkSeg(groupStr);
                loginRecord.setFailReason("");
                loginRecord.setLoginResult("成功");

                loginRecordService.addLoginRecord(loginRecord);

                return ResultUtil.success(map);
            }
            return ResultUtil.error(500, "账号或者密码错误", "Account Or Password Error", null);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(500, e.getMessage(), e.getMessage(), null);
        }
    }


}
